package com.ncloud.aaaa.service.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;

import com.alibaba.dubbo.config.annotation.Service;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.ncloud.aaaa.base.Constant;
import com.ncloud.aaaa.model.User;
import com.ncloud.aaaa.repository.UserRepository;
import com.ncloud.aaaa.service.UserService;
import com.ncloud.aaaa.util.EncryptUtils;
import com.ncloud.auth.config.RedisItem;
import com.ncloud.auth.config.RedisKeys;
import com.ncloud.auth.service.LocalTokenService;
import com.ncloud.common.enmus.ResultEnum;
import com.ncloud.common.exception.UserException;

//import java.util.Optional;

@Service
public class UserServiceImpl implements UserService {
	
	private static final Logger logger = LogManager.getLogger(UserServiceImpl.class);
	@Autowired
	private UserRepository repository;
	@Autowired
	private LocalTokenService tokenService;
	@Autowired
	private UserBusiServiceImpl busi;

	@Override
	public JSONObject addUser(JSONObject obj) {
		//判断参数是否正确
		if(!obj.containsKey("userType") || !obj.containsKey("account")){
			throw new UserException(ResultEnum.PARAM_ERROR);
		}
		
		return busi.addUser(obj);
	}
	
	public Boolean checkUserName(JSONObject obj) {
		Boolean result = true;
		String account = obj.getString("account");
		User user = repository.getByAccount(account);
		if(user != null && user.getAccount().equals(account)){
			result = false;
		}else {
			result = true;
		}
		return result;
	}

	public User getByAccount(String account) {
		//先从redis获取，后续补充
		User user = repository.getByAccount(account);
		if(user == null)
			throw new UserException("账号不存在，请联系管理员");
		if(Constant.FROZEN_STATE.equals(user.getState())){
			throw new UserException("账号被冻结，请联系管理员");
		}else if (Constant.DELETE_STATE.equals(user.getState())) {
			throw new UserException("账号不存在，请联系管理员");
		}
		return user;
	}

	public User addErrTimes(boolean redisCheck, User user) {
		int i = (user.getErrTimes()==null?0:user.getErrTimes())+1;
		//更新redis内次数
		user.setErrTimes(i);
		if(redisCheck){
			List<RedisItem> list = new ArrayList<RedisItem>();
			list.add(new RedisItem(RedisKeys.REDIS_USER_LOGIN_PREFIX+user.getAccount(), user, RedisKeys.REDIS_USER_LOGIN_EXPIRE));
			tokenService.set(list);
			if(i>=Constant.allow_login_err_times){
				user.setErrTimes(i);
				updateUser(user);
			}
		}else{
			updateUser(user);
		}
		return user;
	}

	private User updateUser(User user) {
		user.setUpdateTime(new Date());
		return repository.save(user);
	}

	public User clearErrTimes(boolean redisCheck, User user) {
		
		if(redisCheck){
			if(0<user.getErrTimes()){
				user.setErrTimes(0);
				updateUser(user);
			}
			user.setErrTimes(0);
			busi.updateUserRedis(user);
		}else{
			user.setErrTimes(0);
			updateUser(user);
		}
		return user;
	}

	

	@Override
	public JSONObject changePwd(JSONObject json) {
		if(!json.containsKey("oldPwd") || !json.containsKey("newPwd")){
			throw new UserException(ResultEnum.PARAM_ERROR);
		}
		Long userId =  json.getLong("userID");
		if(userId ==null) throw new UserException("非法操作");
		String oldPwd = json.getString("oldPwd");
		String newPwd = json.getString("newPwd");
		User user = repository.findOne(userId);
		if(!user.getPwd().equals(EncryptUtils.encryptSHA(oldPwd)))
			throw new UserException("2004","旧密码不合法");
		user.setPwd(EncryptUtils.encryptSHA(newPwd));
		user.setUpdateTime(new Date());
		User saveUser=updateUser(user);
		busi.updateUserRedis(saveUser);
		return JSON.parseObject(JSON.toJSONString(saveUser));
	}
	public JSONObject checkAndUpdateNameAndPwd(JSONObject json){
		if(!json.containsKey("oldPwd") || !json.containsKey("newPwd") || !json.containsKey("account")){
			throw new UserException(ResultEnum.PARAM_ERROR);
		}
		Long userId =  json.getLong("userID");
		if(userId ==null) throw new UserException("非法操作");
		String oldPwd = json.getString("oldPwd");
		String newPwd = json.getString("newPwd");
		User user = repository.findOne(userId);
		if(!user.getPwd().equals(EncryptUtils.encryptSHA(oldPwd)))
			throw new UserException("2004","旧密码不合法");
		String account = json.getString("account");
		user.setAccount(account);
		user.setPwd(EncryptUtils.encryptSHA(newPwd));
		user.setUpdateTime(new Date());
		User saveUser=updateUser(user);
		busi.updateUserRedis(saveUser);
		return JSON.parseObject(JSON.toJSONString(saveUser));		
	}
	@Override
	public Object DestoryUser(JSONObject json) {
		//判断传入参数是否合法
		if(!json.containsKey("userId")){
			throw new UserException("2001","传入参数有误");
		}
		Long userID = json.getLong("userID");
		Long userId = json.getLong("userId");
		if(userID.longValue()==userId.longValue()){
			throw new UserException("删除记录为操作员本身，不允许删除！");
		}
		//失效用户
		try {
			User user = repository.findOne(userId);
			user.setState(Constant.DELETE_STATE);
			user.setUpdateTime(new Date());
			user = repository.save(user);
		} catch (Exception e) {
			throw new UserException(ResultEnum.DATABASE_ERROR);
		}
		
		return HttpStatus.OK;
	}

	@Override
	public JSONObject updateNameAndPwd(JSONObject userObj) {
		if(!userObj.containsKey("account") || !userObj.containsKey("pwd")){
			throw new UserException("2001","传入参数有误");
		}
		String userId = userObj.getString("userID");
		User user = repository.findOne(Long.parseLong(userId));
		String account = userObj.getString("account");
		user.setAccount(account);
		String pwd = userObj.getString("pwd");
		user.setPwd(EncryptUtils.encryptSHA(pwd));
		user.setErrTimes(0);
		user = repository.save(user);
		busi.updateUserRedis(user);
		return JSON.parseObject(JSON.toJSONString(user));
	}

	public User updateUserLoginTime(User user) {
		Date now = new Date();
		if(user.getFirstLoginTime()==null)
			user.setFirstLoginTime(now);
		user.setLoginTime(now);
		user.setUpdateTime(now);
		return repository.save(user);
	}

	@Override
	public Long isUserAccount(String account) {
		Long uid = null;
		List<User> list = repository.isUserAccount(account);
		if(list != null && list.size()>0){
			uid = list.get(0).getId();
		}
		return uid;
	}

	@Override
	public Boolean resetUserPwd(JSONObject json) {
		if(!json.containsKey("account"))
			throw new UserException(ResultEnum.PARAM_ERROR);
		String account = json.getString("account");
		String pwd = json.containsKey("pwd")?json.getString("pwd"):account+Constant.USER_PWD_SUFFIX;
//		String userID = json.getString("userID");
		
		User user = getByAccount(account);
		if(account.equals(user.getAccount())){
			user.setPwd(EncryptUtils.encryptSHA(pwd));
			user.setUpdateTime(new Date());
			user.setErrTimes(0);
		}else{
			throw new UserException("账号不匹配！存在非法操作！");
		}
		user = repository.save(user);
		busi.updateUserRedis(user);
		return true;
	}

	@Override
	public Object updateUserInfo(JSONObject json) {
		if(!json.containsKey("userId")){
			throw new UserException(ResultEnum.PARAM_ERROR);
		}
		
		busi.updateUserInfo(json);
		return HttpStatus.OK;
	}

	@Override
	public Object changeUserState(JSONObject json) {
		if(!json.containsKey("action")){
			throw new UserException(ResultEnum.PARAM_ERROR);
		}
		String action = json.getString("action");
		String state = null;
		JSONArray userIds = json.getJSONArray("userIds");
		if(Constant.ACTION_FROZEN.equals(action)){
			state = Constant.FROZEN_STATE;
		}else if (Constant.ACTION_ACTIVATE.equals(action)) {
			state = Constant.NORMAL_STATE;
		}else {
			throw new UserException("传入动作类型不合法！");
		}
		for (Object object : userIds) {
			JSONObject jsonObject = (JSONObject) object;
			Long userId = jsonObject.getLong("userId");
			User user = repository.findOne(userId);
			user.setState(state);
			updateUser(user);
		}
		return HttpStatus.OK;
	}

	@Override
	public JSONObject getUserById(Long userId) {
		User user = repository.findOne(userId);
		return JSON.parseObject(JSON.toJSONString(user));
	}
}
